//
//  JKSpeechRecognizer.m
//  苹果自带语音转文字
//
//  Created by Annie on 2020/5/11.
//  Copyright © 2020 Annie. All rights reserved.
//

#import "JKSpeechRecognizer.h"



#define JKWeakSelf __weak typeof(self) weakSelf = self;
#define JKStrongSelf __strong typeof(weakSelf) strongSelf = weakSelf;



@interface JKSpeechRecognizer ()<SFSpeechRecognizerDelegate>

/// 语音识别器
@property (nonatomic, strong) SFSpeechRecognizer *speechRecognizer;

/// 语音识别请求
@property (nonatomic,strong) SFSpeechAudioBufferRecognitionRequest *recognitionRequest;

/// 语音任务管理器
@property (nonatomic, strong) SFSpeechRecognitionTask *recognitionTask;

/// 语音控制器
@property (nonatomic,strong) AVAudioEngine *audioEngine;

@end

@implementation JKSpeechRecognizer

#pragma mark - SFSpeechRecognizerDelegate
// Called when the availability of the given recognizer changes
- (void)speechRecognizer:(SFSpeechRecognizer *)speechRecognizer availabilityDidChange:(BOOL)available{
    
}

/// 发送语音认证请求(首先要判断设备是否支持语音识别功能)
/// @param resultBlock 结果回调
- (void)requestAuthorizationWithResult:(void(^)(BOOL authorized))resultBlock{
    
    [SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus status) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (resultBlock) {
                resultBlock(status == SFSpeechRecognizerAuthorizationStatusAuthorized);
            }
        });
        switch (status) {
            case SFSpeechRecognizerAuthorizationStatusNotDetermined:
                NSLog(@"%@",@"功能不可用");
                break;
            case SFSpeechRecognizerAuthorizationStatusDenied:
                NSLog(@"%@",@"功能不可用");
                break;
            case SFSpeechRecognizerAuthorizationStatusRestricted:
                NSLog(@"%@",@"功能不可用");
                break;
            case SFSpeechRecognizerAuthorizationStatusAuthorized:
                NSLog(@"%@",@"ok");
//                [self initialiseInputNode];
                [self configAudioSession];
                break;
            default:
               NSLog(@"%@",@"???");
                break;
        }
        
    }];
}

#pragma mark----语音识别
- (SFSpeechRecognizer *)speechRecognizer{
    if (!_speechRecognizer) {
        NSLocale *cale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh-CN"];
        SFSpeechRecognizer *speechRecognizer = [[SFSpeechRecognizer alloc] initWithLocale:cale];
        speechRecognizer.delegate = self;
        _speechRecognizer = speechRecognizer;
    }
    return _speechRecognizer;
}


- (AVAudioEngine *)audioEngine{
    if (!_audioEngine) {
        AVAudioEngine *audioEngine = [[AVAudioEngine alloc] init];
        _audioEngine = audioEngine;
    }
    return _audioEngine;
}



- (BOOL)configAudioSession{
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    NSError *error;
    BOOL res = [audioSession setCategory:AVAudioSessionCategoryRecord error:&error];
    NSParameterAssert(!error);
    BOOL res1 = [audioSession setMode:AVAudioSessionModeMeasurement error:&error];
    NSParameterAssert(!error);
    BOOL res2 = [audioSession setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&error];
    NSParameterAssert(!error);
    BOOL ok = res || res1 || res2;
    if(ok) {
        NSLog(@"可以使用");
    }else{
        NSLog(@"这里说明有的功能不支持");
    }
    return ok;
}

- (void)startRecognition{
    if (self.recognitionTask) {
        [self.recognitionTask cancel];
        self.recognitionTask = nil;
    }
    
    self.recognitionRequest = [[SFSpeechAudioBufferRecognitionRequest alloc] init];
    AVAudioInputNode *inputNode = self.audioEngine.inputNode;
    NSAssert(inputNode,@"录入设备没有准备好");
    NSAssert(self.recognitionRequest, @"请求初始化失败");
    self.recognitionRequest.shouldReportPartialResults = true;


        

    JKWeakSelf
    self.recognitionTask = [self.speechRecognizer recognitionTaskWithRequest:self.recognitionRequest resultHandler:^(SFSpeechRecognitionResult * _Nullable result, NSError * _Nullable error) {
        
        
        if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(speechRecognizer:result:error:)]) {
            [weakSelf.delegate speechRecognizer:self result:result error:error];
        }
//        if (result) {
//            NSString *text= [[result bestTranscription] formattedString];//语音转文本
//            [result isFinal];
//            weakSelf.audioTextLabel.text = text;
//
//
//        }else{
//            NSLog(@"%@-%@",@"没有结果",error);
//        }
    }];
    AVAudioFormat *recordingFormat = [inputNode outputFormatForBus:0];
    [inputNode removeTapOnBus:0];
    
    [inputNode installTapOnBus:0 bufferSize:1024 format:recordingFormat block:^(AVAudioPCMBuffer * _Nonnull buffer, AVAudioTime * _Nonnull when) {
        JKStrongSelf

        if (strongSelf.recognitionRequest) {
            [strongSelf.recognitionRequest appendAudioPCMBuffer:buffer];
        }
    }];
    
    [self.audioEngine prepare];
    NSError *error;
    BOOL res3 = [self.audioEngine startAndReturnError:&error];
    NSParameterAssert(!error);
}
- (void)endRecognition{
    [self.audioEngine stop];
    if (self.recognitionRequest) {
        [self.recognitionRequest endAudio];
    }
}

@end
